import processing.core.*;
public class Hahmo {

	private float prevBez;
	private PApplet p;
	private float anim;
	private float count;
	private int vari;
	private boolean animate;
	
	/**
	 * Hahmo-luokka vastaa mursujen 3D-mallinnoksesta. Kutsumalla Hahmo-olion piirra()-metodia piirretaan 3D-mursu! (melkein kuin mersu!)
	 * @param pa - emanta PApplet
	 * @param animate - animaatio on-off
	 * @param color - pelaajan nro, eli 1, 2 tai 3.
	 */
	public Hahmo(PApplet pa, boolean animate, int color)
	{
		this.p = pa;
		this.anim = 0;
		this.count = 0;
		this.animate = animate;
		this.vari = color;
		
	}

	public void keho()
	{
		int steps = 20;
		p.beginShape(PApplet.QUAD_STRIP);
		float bezKoko = prevBez;
		int b = 0;
		for (int a = 10; a > 0; a--)
		{
			if(a>0)
				bezKoko = PApplet.sqrt((a-2)*400);
			for (int i = 0; i <= steps; i++)
			{
				float t = i / (float) steps;
				float x1 = p.bezierPoint(-prevBez/2, -prevBez, prevBez, prevBez/2, t);
				float y1 = p.bezierPoint(-prevBez/2, prevBez, prevBez, -prevBez/2, t);
				float x2 = p.bezierPoint(-bezKoko/2, -bezKoko, bezKoko, bezKoko/2, t);
				float y2 = p.bezierPoint(-bezKoko/2, bezKoko, bezKoko, -bezKoko/2, t);
				p.vertex(x1, 	y1+b*5, 			(b-1)*5);
				p.vertex(x2, 	y2+(b+1)*5,			 b*5);
				if(i==steps)
				{
					x1 = p.bezierPoint(-prevBez/2, -prevBez, prevBez, prevBez/2, 0);
					y1 = p.bezierPoint(-prevBez/2, prevBez, prevBez, -prevBez/2, 0);
					x2 = p.bezierPoint(-bezKoko/2, -bezKoko, bezKoko, bezKoko/2, 0);
					y2 = p.bezierPoint(-bezKoko/2, bezKoko, bezKoko, -bezKoko/2, 0);
					p.vertex(x1, 	y1+b*5, 			(b-1)*5);
					p.vertex(x2, 	y2+(b+1)*5,		b*5);
				}
			}
			prevBez = bezKoko;
			b++;
		}
		p.endShape();
	}

	public void pyrsto()
	{
		int steps = 20;
		p.beginShape(PApplet.QUAD_STRIP);
		prevBez = 0;
		for (int a = 0; a < 10; a++){
			float bezKoko = PApplet.sqrt(a*400);
			for (int i = 0; i <= steps; i++){
				float t = i / (float) steps;
				float x1 = p.bezierPoint(-prevBez/2, -prevBez, prevBez, prevBez/2, t);
				float y1 = p.bezierPoint(-prevBez/2, prevBez, prevBez, -prevBez/2, t);
				float x2 = p.bezierPoint(-bezKoko/2, -bezKoko, bezKoko, bezKoko/2, t);
				float y2 = p.bezierPoint(-bezKoko/2, bezKoko, bezKoko, -bezKoko/2, t);
				p.vertex(x1, y1, (a-1)*10+20*anim);
				
				p.vertex(x2, y2, a*10+20*anim);
				if(a<9)
				{
				if(i==steps)
				{
					x1 = p.bezierPoint(-prevBez/2, -prevBez, prevBez, prevBez/2, 0);
					y1 = p.bezierPoint(-prevBez/2, prevBez, prevBez, -prevBez/2, 0);
					x2 = p.bezierPoint(-bezKoko/2, -bezKoko, bezKoko, bezKoko/2, 0);
					y2 = p.bezierPoint(-bezKoko/2, bezKoko, bezKoko, -bezKoko/2, 0);
					p.vertex(x1, y1, (a-1)*10+20*anim);
					p.vertex(x2, y2, a*10+20*anim);
				}
				}
			}
			prevBez = bezKoko;
		}
		p.endShape();
	}

	public void paa()
	{
		p.pushMatrix();
		p.translate(0,-45,10);
		hampaat();
		p.popMatrix();
		p.pushMatrix();
		p.translate(-5, 10, 10);
		simmut();
		p.popMatrix();

	}
	public void simmut()
	{
		p.sphereDetail(5);
		p.fill(150,150,255);
		p.pushMatrix();
		p.sphere(6);
		p.translate(10, 0, 0);
		p.sphere(6);
		p.popMatrix();
		
	}
	public void hampaat()
	{
		p.fill(255);
		p.pushMatrix();
		p.rotateZ(PApplet.PI);
		p.rotateX((float)1.7);
		p.translate(-10,0,0);
		hammas();
		p.translate(20,0,0);
		hammas();
		p.popMatrix();
	}
	public void hammas()
	{
		int steps = 5;
		p.beginShape(PApplet.QUAD_STRIP);
		float bezKoko = prevBez = 0;
		for (int a = 0; a < 10; a++)
		{
			bezKoko = PApplet.sqrt(a*30);
			for (int i = 0; i <= steps; i++)
			{
				float t = i / (float) steps;
				float x1 = p.bezierPoint(0, -prevBez, prevBez, 0, t);
				float y1 = p.bezierPoint(0, prevBez/2, prevBez/2, 0, t);
				float x2 = p.bezierPoint(0, -bezKoko, bezKoko, 0, t);
				float y2 = p.bezierPoint(0, bezKoko/2, bezKoko/2, 0, t);
				p.vertex(x1, y1, (a-1)*5);
				p.vertex(x2, y2, a*5);
			}
			prevBez = bezKoko;
		}
		p.endShape();
	}
	public void evat()
	{
		//p.fill(140,50,20);
		p.pushMatrix();
		eva();
		p.rotateY((float)0.3);
		eva();
		p.rotateY((float)0.3);
		eva();
		p.rotateY((float)0.3);
		eva();
		p.popMatrix();
	}
	public void eva()
	{
		int steps = 3;
		p.beginShape(PApplet.QUAD_STRIP);
		float bezKoko = prevBez = 0;
		int a;
		for (a = 0; a < 10; a++)
		{
			bezKoko = PApplet.sqrt(a*30);
			for (int i = 0; i <= steps; i++)
			{
				float t = i / (float) steps;
				float x1 = p.bezierPoint(-prevBez/2, -prevBez, prevBez, prevBez/2, t);
				float y1 = p.bezierPoint(0, prevBez/2, prevBez/2, 0, t);
				float x2 = p.bezierPoint(-bezKoko/2, -bezKoko, bezKoko, bezKoko/2, t);
				float y2 = p.bezierPoint(0, bezKoko/2, bezKoko/2, 0, t);
				p.vertex(x1, y1, (a-1)*5);
				p.vertex(x2, y2, a*5);
				if(i==steps)
				{
					x1 = p.bezierPoint(-prevBez/2, -prevBez, prevBez, prevBez/2, 0);
					y1 = p.bezierPoint(0, prevBez/2, prevBez/2, 0, 0);
					x2 = p.bezierPoint(-bezKoko/2, -bezKoko, bezKoko, bezKoko/2, 0);
					y2 = p.bezierPoint(0, bezKoko/2, bezKoko/2, 0, 0);
					p.vertex(x1, 	y1, 	(a-1)*5);
					p.vertex(x2, 	y2,		a*5);
				}
			}
			prevBez = bezKoko;
		}
		p.endShape();
		steps = 3;
		p.pushMatrix();
		p.translate(0,0,47);
		p.beginShape(PApplet.QUAD_STRIP);
		bezKoko = prevBez;
		int b = 0;
		for (; a > 0; a--)
		{
			if(a>0)
				bezKoko = PApplet.sqrt((a-2)*30);
			for (int i = 0; i <= steps; i++)
			{
				float t = i / (float) steps;
				float x1 = p.bezierPoint(-prevBez/2, -prevBez, prevBez, prevBez/2, t);
				float y1 = p.bezierPoint(0, prevBez/2, prevBez/2, 0, t);
				float x2 = p.bezierPoint(-bezKoko/2, -bezKoko, bezKoko, bezKoko/2, t);
				float y2 = p.bezierPoint(0, bezKoko/2, bezKoko/2, 0, t);
				p.vertex(x1, 	y1, 			(b-1)*2);
				p.vertex(x2, 	y2,			 b*2);
				if(i==steps)
				{
					x1 = p.bezierPoint(-prevBez/2, -prevBez, prevBez, prevBez/2, 0);
					y1 = p.bezierPoint(0, prevBez/2, prevBez/2, 0, 0);
					x2 = p.bezierPoint(-bezKoko/2, -bezKoko, bezKoko, bezKoko/2, 0);
					y2 = p.bezierPoint(0, bezKoko/2, bezKoko/2, 0, 0);
					p.vertex(x1, 	y1, 			(b-1)*2);
					p.vertex(x2, 	y2,		b*2);
				}
			}
			prevBez = bezKoko;
			b++;
		}
		p.endShape();
		p.popMatrix();
	}
	
	public void jalat()
	{
		evat();
		p.pushMatrix();
		p.rotateY((float)3);
		p.translate(10,0,20);
		evat();
		p.popMatrix();
	}
	
	public void mainVari()
	{
		if(vari == 1)
			p.fill(0,150,50);
		else if(vari == 2)
			p.fill(255,150,150);
		else if(vari == 3)
			p.fill(140,70,20);
	}
	
	public void secVari()
	{
		if(vari == 1)
			p.fill(0,100,30);
		else if(vari == 2)
			p.fill(240,100,100);
		else if(vari == 3)
			p.fill(140,70,20);
	}
	public void mursu()
	{
		p.pushMatrix();
		p.rotateZ(PApplet.PI);
		p.noStroke();
		this.secVari();
		
		p.pushMatrix();
		p.translate(0, -5, 15);
		p.rotateY((float)2.6);
		p.rotateY((float)anim);
		this.evat();
		p.popMatrix();
		
		this.mainVari();
		this.pyrsto();
		
		p.pushMatrix();
		p.translate(0,0,95);
		
		p.translate(0, 0, -5);
		p.rotateX(anim);
		
		this.keho();
		p.translate(0, 35, 24);
		this.paa();
		p.popMatrix();
	
		p.pushMatrix();
		p.translate(-13, -20, 90);
		p.rotateY(-(float)1.9);
		p.rotateX((float)0);
		this.secVari();
		jalat();
		p.popMatrix();
		
		if(animate)
		{
			this.anim = (float)0.1*PApplet.sin(count);
			this.count += 0.2;
		}
		p.popMatrix();
	}
}
